#include "scanresults.h"

// Qt Includes
#include <QtDebug>
#include <QList>
#include <QObject>
#include <QSqlQuery>
#include <QVariant>

// Namespaces
using namespace NScanResultRecords;

/////////////////////////////////////////////////////////////////////
// Construction & Destruction
/////////////////////////////////////////////////////////////////////
CScanResults::CScanResults(const QString &strDatabaseName)
{
	// The results are stored in an SQLite database.
	m_theDatabase = QSqlDatabase::addDatabase("QSQLITE");
	m_theDatabase.setDatabaseName(strDatabaseName);

	// We don't care about whether the database opens successfully or not here
	// as we have no way of reporting it back to the user.
	m_theDatabase.open();
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Member Functions
/////////////////////////////////////////////////////////////////////
QList<quint8> CScanResults::getSeverities() const
{
	QList<quint8> lstSeverities;

	if(!m_theDatabase.isOpen())
		return lstSeverities;

	QString strQuery(QObject::tr(
			"SELECT DISTINCT Results.severity "
			"FROM Results"));
	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return lstSeverities;

	if(theQuery.exec())
	{
		while(theQuery.next())
		{
			lstSeverities.append(theQuery.value(0).toUInt());
		}
	}

	return lstSeverities;
}

QList<NScanResultRecords::PluginRecord> CScanResults::getPlugins(bool bWithoutResults/* = true*/) const
{
	QList<PluginRecord> lstPlugins;

	if(!m_theDatabase.isOpen())
		return lstPlugins;

	QString strQuery(QObject::tr(
			"SELECT Plugins.id, Plugins.name, Plugins.desc "
			"FROM Plugins"));

	if(!bWithoutResults)
	{
		strQuery += " WHERE Plugins.id IN (SELECT Results.pluginId FROM Results)";
	}

	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return lstPlugins;

	if(theQuery.exec())
	{
		while(theQuery.next())
		{
			lstPlugins.append(PluginRecord(theQuery.value(0).toUInt(), theQuery.value(1).toString(),
					theQuery.value(2).toString()));
		}
	}

	return lstPlugins;
}

QList<FileRecord> CScanResults::getFiles(bool bWithoutResults/* = true*/) const
{
	QList<FileRecord> lstFiles;

	if(!m_theDatabase.isOpen())
		return lstFiles;

	QString strQuery(QObject::tr(
			"SELECT Files.id, Files.name "
			"FROM Files"));

	if(!bWithoutResults)
	{
		strQuery += " WHERE Files.id IN (SELECT Results.fileId FROM Results)";
	}

	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return lstFiles;

	if(theQuery.exec())
	{
		while(theQuery.next())
		{
			lstFiles.append(FileRecord(theQuery.value(0).toUInt(), theQuery.value(1).toString()));
		}
	}

	return lstFiles;
}

QList<NScanResultRecords::ResultRecord> CScanResults::getResultsBySeverity(quint8 nSeverity) const
{
	QList<ResultRecord> lstRecords;

	if(!m_theDatabase.isOpen())
		return lstRecords;

	QString strQuery(QObject::tr(
			"SELECT Results.id, Results.pluginId, Results.fileId, Results.col, Results.lineSpan, "
				"Results.line, Results.code "
			"FROM Results "
			"WHERE Results.severity = ?"));
	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return lstRecords;

	theQuery.bindValue(0, nSeverity);

	if(theQuery.exec())
	{
		while(theQuery.next())
		{
			lstRecords.append(ResultRecord(
					theQuery.value(0).toUInt(),
					theQuery.value(1).toUInt(),
					theQuery.value(2).toUInt(),
					theQuery.value(3).toUInt(),
					theQuery.value(4).toUInt(),
					theQuery.value(5).toUInt(),
					nSeverity,
					theQuery.value(6).toString()));
		}
	}

	return lstRecords;
}

QList<NScanResultRecords::ResultRecord> CScanResults::getResultsByPluginID(quint32 nPluginID) const
{
	QList<ResultRecord> lstResults;

	if(!m_theDatabase.isOpen())
		return lstResults;

	QString strQuery(QObject::tr(
			"SELECT Results.id, Results.fileId, Results.col, Results.lineSpan, "
				"Results.line, Results.severity, Results.code "
			"FROM Results "
			"WHERE Results.pluginId = ?"));
	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return lstResults;

	theQuery.bindValue(0, nPluginID);

	if(theQuery.exec())
	{
		while(theQuery.next())
		{
			lstResults.append(ResultRecord(
					theQuery.value(0).toUInt(),
					nPluginID,
					theQuery.value(1).toUInt(),
					theQuery.value(2).toUInt(),
					theQuery.value(3).toUInt(),
					theQuery.value(4).toUInt(),
					theQuery.value(5).toUInt(),
					theQuery.value(6).toString()));
		}
	}

	return lstResults;
}

QList<NScanResultRecords::ResultRecord> CScanResults::getResultsByFileID(quint32 nFileID) const
{
	QList<ResultRecord> lstResults;

	if(!m_theDatabase.isOpen())
		return lstResults;

	QString strQuery(QObject::tr(
			"SELECT Results.id, Results.pluginId, Results.col, Results.lineSpan, "
				"Results.line, Results.severity, Results.code "
			"FROM Results "
			"WHERE Results.fileId = ?"));
	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return lstResults;

	theQuery.bindValue(0, nFileID);

	if(theQuery.exec())
	{
		while(theQuery.next())
		{
			lstResults.append(ResultRecord(
					theQuery.value(0).toUInt(),
					theQuery.value(1).toUInt(),
					nFileID,
					theQuery.value(2).toUInt(),
					theQuery.value(3).toUInt(),
					theQuery.value(4).toUInt(),
					theQuery.value(5).toUInt(),
					theQuery.value(6).toString()));
		}
	}

	return lstResults;
}

NScanResultRecords::PluginRecord CScanResults::getPluginByID(quint32 nPluginID) const
{
	NScanResultRecords::PluginRecord thePluginRecord;

	if(!m_theDatabase.isOpen())
		return thePluginRecord;

	QString strQuery(QObject::tr(
			"SELECT Plugins.id, Plugins.name, Plugins.desc "
			"FROM Plugins "
			"WHERE Plugins.id = ?"));
	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return thePluginRecord;

	theQuery.bindValue(0, nPluginID);

	if(theQuery.exec())
	{
		if(theQuery.next())
		{
			thePluginRecord.id = theQuery.value(0).toUInt();
			thePluginRecord.name = theQuery.value(1).toString();
			thePluginRecord.desc = theQuery.value(2).toString();
		}
	}

	return thePluginRecord;
}

NScanResultRecords::FileRecord CScanResults::getFileByID(quint32 nFileID) const
{
	NScanResultRecords::FileRecord theFileRecord;

	if(!m_theDatabase.isOpen())
		return theFileRecord;

	QString strQuery(QObject::tr(
			"SELECT Files.id, Files.name "
			"FROM Files "
			"WHERE Files.id = ?"));
	QSqlQuery theQuery(m_theDatabase);

	if(!theQuery.prepare(strQuery))
		return theFileRecord;

	theQuery.bindValue(0, nFileID);

	if(theQuery.exec())
	{
		if(theQuery.next())
		{
			theFileRecord.id = theQuery.value(0).toUInt();
			theFileRecord.name = theQuery.value(1).toString();
		}
	}

	return theFileRecord;
}
/////////////////////////////////////////////////////////////////////
